package com.eascs.file;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.eascs.admin.common.controller.BaseMasterViewController;
import com.eascs.app.context.ConfigContext;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.common.dfs.fastdfs.FastDfsClient;
import com.eascs.common.exception.RuntimeIOException;
import com.eascs.common.ftp.FtpConfig;
import com.eascs.common.ftp.FtpHelper;
import com.eascs.common.http.HTTPResponse;
import com.eascs.common.http.HttpClients;
import com.eascs.common.util.EncodingUtil;
import com.eascs.common.util.StopWatch;
import com.eascs.datalist.entity.O2oDataListEntity;
import com.eascs.datalist.service.O2oDataListService;
import com.eascs.file.form.FileForm;

@Controller
public class FileDemoAction extends BaseMasterViewController {
	private final Logger logger = LoggerFactory.getLogger(FileDemoAction.class);

	@Autowired
	private O2oDataListService o2oDataListService;
	@Autowired
	private FileService fileService;
	@Autowired
	private FastDfsClient fastDfsClient;

	private HttpClients httpClients = new HttpClients();

	@Inject
	private FtpConfig ftpConfig;

	@RequestMapping(value = "/file/")
	public String index() {
		return "/file/index";
	}

	@RequestMapping(value = "/file/upload")
	public String upload(@RequestParam(value = "file", required = false) MultipartFile file, String datalistCode, String loanapplyno) {
		logger.debug("name={},originalFilename={},size={},contextType={},", file.getName(), file.getOriginalFilename(), file.getSize(), file.getContentType());
		fileService.upload(file, datalistCode, loanapplyno);
		return "/file/index";
	}

	@RequestMapping(value = "/file/download")
	public void download(FileForm fileForm, HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest) {
		logger.debug("FileForm:[{}]", fileForm.toString());
		O2oDataListEntity attachment = o2oDataListService.findO2oDataListEntity(fileForm.getDatalistno());
		if ("pdf".equals(attachment.getExtendNmae())) {
			httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + EncodingUtil.urlEncode(attachment.getOriginalName()));
			httpServletResponse.setContentType("application/octet-stream; charset=utf-8");
		} else if (fastDfsClient.isImgPath(attachment.getExtendNmae())) {
			httpServletResponse.setContentType("image/" + attachment.getExtendNmae());
		}else if("html".equals(attachment.getExtendNmae())){
			httpServletResponse.setContentType("text/html; charset=GBK");
		} else {
			try {
				httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(attachment.getOriginalName(), "utf-8"));
				httpServletResponse.setContentType("application/octet-stream; charset=utf-8");
			} catch (UnsupportedEncodingException e) {
				logger.error("UnsupportedEncodingException:[{}]", e.getMessage());
			}
		}
		viewFile(fileForm, attachment, httpServletResponse, httpServletRequest);
		return;
	}

	private void viewFile(FileForm fileForm, O2oDataListEntity attachment, HttpServletResponse httpServletResponse, HttpServletRequest request) {
		String filePath = attachment.getUrlpath();
		if (!fastDfsClient.isFastDfsPath(filePath)) {
			StopWatch watch = new StopWatch();
			try {
				ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
				FtpHelper.download(ftpConfig, byteArrayOutputStream, filePath);
				logger.debug("download from ftp, filePath={}, elapsedTime={},byteArrayOutputStream.size()={}", filePath, watch.elapsedTime(), byteArrayOutputStream.size());
				ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
				filePath = fastDfsClient.uploadInputStream(byteArrayInputStream, fastDfsClient.buildFastDfsPath(filePath, "grouploan", fileForm.getConvertType()), null);
				logger.info("FastDFS uploadPath:[{}]", filePath);
				attachment.setUrlpath(filePath);
				o2oDataListService.updateEntityById(attachment);
			} catch (Exception e) {
				logger.error("File FTP copy FastDFS error：[{}]", e.getMessage());
				throw new RuntimeIOException(e);
			} finally {
				logger.debug("upload to fastdfs, filePath={}, elapsedTime={}", filePath, watch.elapsedTime());
			}
		}
		try {
			httpServletResponse.getOutputStream().write(fastDfsClient.downloadFile(filePath));
			if (null != filePath)
				return;
			filePath = ConfigContext.getStringValue("fastdfs.http_storage_server") + fastDfsClient.buildFastDfsPath(filePath, ConfigContext.getStringValue("fastdfs.group_name"), fileForm.getConvertType());
			logger.debug("forward to filePath={}", fastDfsClient.buildFastDfsPath(filePath, ConfigContext.getStringValue("fastdfs.group_name"), fileForm.getConvertType()));
			HTTPResponse response = httpClients.getAndResponse(filePath, null);
			byte[] bits = response.responseBinary();
			logger.info("img bits size[{}]", bits.length);
			httpServletResponse.getOutputStream().write(bits);
		} catch (IOException e) {
			throw new RuntimeIOException(e);
		}
	}
}
